<template>
  <div
    class="bg-white rounded-lg p-5 shadow-sm h-full flex flex-col overflow-hidden"
  >
    <h2 class="text-lg font-medium mb-4">Energy Flow Diagram</h2>

    <div class="relative flex-1 min-h-[400px]">
      <!-- D3 图表容器 -->
      <div ref="containerRef" class="energy-flow-container w-full h-full"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";
import * as d3 from "d3";
import { EnergyFlowData } from "../../data"; // getMockEnergyFlowData

// 导入图片资源
import solarActiveImg from "./assets/solar-active.png";
import solarInactiveImg from "./assets/solar-deactive.png";
import homeActiveImg from "./assets/home-active.png";
import homeInactiveImg from "./assets/home-deactive.png";
import batteryActiveImg from "./assets/battery-active.png";
import batteryInactiveImg from "./assets/battery-deactive.png";
import gridActiveImg from "./assets/grid-active.png";
import gridInactiveImg from "./assets/grid-deactive.png";

// 连线数据类型定义
interface LinkData {
  id: string;
  source: string;
  target: string;
  type:
    | "vertical"
    | "horizontal"
    | "corner-left"
    | "corner-right"
    | "corner-down";
  hasFlow: boolean; // 是否有粒子流动
  flowDirection: "forward" | "reverse"; // 流动方向：forward(source->target) | reverse(target->source)
  gradient: {
    id: string;
    colors: Array<{
      offset: string;
      color: string;
    }>;
  };
}

// 画布配置接口
interface CanvasConfig {
  enableZoom: boolean; // 是否启用缩放
  enableDrag: boolean; // 是否启用拖拽
  width: number; // 画布宽度
  height: number; // 画布高度
  background: string; // 背景色
}

// 默认画布配置
const defaultCanvasConfig: CanvasConfig = {
  enableZoom: false, // 禁用缩放
  enableDrag: false, // 禁用拖拽
  width: 400, // 初始默认值，会被动态更新
  height: 300, // 初始默认值，会被动态更新
  background: "#ffffff"
};

const props = defineProps<{
  systemId: string;
}>();

const containerRef = ref<HTMLDivElement>();
const flowData = ref<EnergyFlowData>({
  solar: { power: 0 },
  grid: { power: 0 },
  battery: { power: 0 },
  load: { power: 0 }
}); // getMockEnergyFlowData());
let svg: d3.Selection<SVGSVGElement, unknown, null, undefined>;
let animationTimeouts: number[] = [];

// 响应式容器尺寸 - 初始值为null，等待动态获取
const containerSize = ref({ width: 0, height: 0 });

// 计算响应式尺寸 - 完全基于实际容器尺寸
const updateContainerSize = () => {
  if (!containerRef.value) return;
  const rect = containerRef.value.getBoundingClientRect();
  containerSize.value = {
    width: rect.width || 400, // 使用实际宽度，fallback为400
    height: rect.height || 300 // 使用实际高度，fallback为300
  };
};

// 加载能源统计数据 - 已注释，使用模拟数据
// const loadEnergyData = async () => {
//   if (!props.systemId) return;
//   
//   try {
//     const data = await getEnergyStats(props.systemId);
//     if (data) {
//       flowData.value = data;
//     }
//   } catch (error) {
//     console.error('加载能源统计数据失败:', error);
//   }
// };

// 获取能源类型的图片
const getEnergyImage = (energyType: string, isActive: boolean) => {
  const imageMap = {
    solar: isActive ? solarActiveImg : solarInactiveImg,
    load: isActive ? homeActiveImg : homeInactiveImg,
    battery: isActive ? batteryActiveImg : batteryInactiveImg,
    grid: isActive ? gridActiveImg : gridInactiveImg
  };
  return imageMap[energyType as keyof typeof imageMap] || solarInactiveImg;
};

// 能源系统节点数据配置 - 根据容器尺寸自适应计算位置
const nodeData = computed(() => {
  const { width, height } = containerSize.value;

  // 如果容器尺寸还未获取，返回空数组
  if (width === 0 || height === 0) {
    return [];
  }

  const centerX = width / 2;
  const centerY = height / 2;

  // 动态计算边距，基于容器尺寸的比例
  const marginX = Math.max(60, width * 0.12); // 横向边距：最小60px或宽度的12%
  const marginY = Math.max(50, height * 0.15); // 纵向边距：最小50px或高度的15%

  return [
    {
      id: "solar",
      label: "Solar",
      power: `${flowData.value.solar.power} kW`,
      image: getEnergyImage("solar", flowData.value.solar.power > 0),
      x: centerX, // 画布中心上方
      y: marginY,
      color: "#FF9800" // 金黄色主题
    },
    {
      id: "load",
      label: "Load",
      power: `${flowData.value.load.power} kW`,
      image: getEnergyImage("load", flowData.value.load.power > 0),
      x: marginX, // 画布左侧，动态边距
      y: centerY,
      color: "#2196F3" // 天蓝色主题
    },
    {
      id: "grid",
      label: "Grid",
      power: `${flowData.value.grid.power} kW`,
      image: getEnergyImage("grid", flowData.value.grid.power > 0),
      x: width - marginX, // 画布右侧，动态边距
      y: centerY,
      color: "#9C27B0" // 紫色主题
    },
    {
      id: "battery",
      label: "Battery",
      power: `${flowData.value.battery.power} kW`,
      image: getEnergyImage("battery", flowData.value.battery.power > 0),
      x: centerX, // 画布中心下方
      y: height - marginY,
      color: "#00BCD4" // 青色主题
    }
  ];
});

// 能源流连线数据配置 - 根据flowData动态计算
const linkData = computed((): LinkData[] => [
  {
    id: "solar-battery",
    source: "solar",
    target: "battery",
    type: "vertical",
    hasFlow: flowData.value.solar.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "solarBatteryGradient",
      colors: [
        { offset: "0%", color: "#FFD700" },
        { offset: "50%", color: "#FF6347" },
        { offset: "100%", color: "#4169E1" }
      ]
    }
  },
  {
    id: "solar-load",
    source: "solar",
    target: "load",
    type: "corner-left",
    hasFlow: flowData.value.solar.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "solarLoadGradient",
      colors: [
        { offset: "0%", color: "#FFD700" },
        { offset: "50%", color: "#FFA500" },
        { offset: "100%", color: "#87CEEB" }
      ]
    }
  },
  {
    id: "solar-grid",
    source: "solar",
    target: "grid",
    type: "corner-right",
    hasFlow: flowData.value.solar.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "solarGridGradient",
      colors: [
        { offset: "0%", color: "#FFD700" },
        { offset: "50%", color: "#FFA500" },
        { offset: "100%", color: "#DDA0DD" }
      ]
    }
  },
  {
    id: "load-battery",
    source: "load",
    target: "battery",
    type: "corner-down",
    hasFlow: flowData.value.load.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "loadBatteryGradient",
      colors: [
        { offset: "0%", color: "#87CEEB" },
        { offset: "50%", color: "#20B2AA" },
        { offset: "100%", color: "#00CED1" }
      ]
    }
  },
  {
    id: "load-grid",
    source: "load",
    target: "grid",
    type: "horizontal",
    hasFlow: flowData.value.load.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "loadGridGradient",
      colors: [
        { offset: "0%", color: "#00BFFF" },
        { offset: "50%", color: "#FF1493" },
        { offset: "100%", color: "#9932CC" }
      ]
    }
  },
  {
    id: "grid-battery",
    source: "grid",
    target: "battery",
    type: "corner-down",
    hasFlow: flowData.value.grid.power > 0,
    flowDirection: "forward",
    gradient: {
      id: "gridBatteryGradient",
      colors: [
        { offset: "0%", color: "#DDA0DD" },
        { offset: "50%", color: "#9370DB" },
        { offset: "100%", color: "#00CED1" }
      ]
    }
  }
]);

/**
 * 创建粒子流动动画
 */
const createParticleAnimation = (
  linkGroup: d3.Selection<SVGGElement, unknown, null, undefined>,
  pathElement: d3.Selection<SVGPathElement, unknown, null, undefined>,
  link: LinkData,
  particleCount: number = 1
) => {
  if (!link.hasFlow) return;

  for (let i = 0; i < particleCount; i++) {
    const circle = linkGroup
      .append("circle")
      .attr("r", 3)
      .attr("fill", link.gradient.colors[1].color)
      .attr("stroke", "#ffffff")
      .attr("stroke-width", 1)
      .style("filter", "drop-shadow(0px 1px 2px rgba(0,0,0,0.3))");

    const pathLength = pathElement.node()!.getTotalLength();

    const animateCircle = () => {
      circle
        .attr("opacity", 0)
        .transition()
        .duration(100)
        .attr("opacity", 1)
        .transition()
        .duration(1500)
        .ease(d3.easeLinear)
        .attrTween("transform", () => {
          return (t: number) => {
            const progress = link.flowDirection === "reverse" ? 1 - t : t;
            const point = pathElement
              .node()!
              .getPointAtLength(progress * pathLength);
            return `translate(${point.x}, ${point.y})`;
          };
        })
        .transition()
        .duration(100)
        .attr("opacity", 0)
        .on("end", () => {
          const timeoutId = setTimeout(animateCircle, i * 500);
          animationTimeouts.push(timeoutId);
        });
    };

    const timeoutId = setTimeout(animateCircle, i * 500);
    animationTimeouts.push(timeoutId);
  }
};

/**
 * 清理所有动画
 */
const clearAllAnimations = () => {
  animationTimeouts.forEach(timeoutId => clearTimeout(timeoutId));
  animationTimeouts = [];

  if (svg) {
    svg.selectAll("*").interrupt();
  }
};

/**
 * 创建能源流图的主函数
 */
const createEnergyFlow = () => {
  if (!containerRef.value) return;

  // 更新容器尺寸
  updateContainerSize();

  const { width, height } = containerSize.value;

  // 如果容器尺寸无效，不执行绘制
  if (width === 0 || height === 0) {
    return;
  }

  // 清理之前的动画和内容
  clearAllAnimations();
  d3.select(containerRef.value).selectAll("*").remove();

  // 创建SVG
  svg = d3
    .select(containerRef.value)
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .style("border-radius", "8px")
    .style("background", defaultCanvasConfig.background);

  // 创建SVG定义容器
  const defs = svg.append("defs");

  // 创建线条渐变定义
  linkData.value.forEach(link => {
    const gradient = defs
      .append("linearGradient")
      .attr("id", link.gradient.id)
      .attr("gradientUnits", "userSpaceOnUse");

    // 根据连线类型和实际节点位置设置渐变方向和坐标
    const sourceNode = nodeData.value.find(n => n.id === link.source);
    const targetNode = nodeData.value.find(n => n.id === link.target);

    if (link.type === "vertical" && sourceNode && targetNode) {
      gradient
        .attr("x1", sourceNode.x.toString())
        .attr("y1", (sourceNode.y + 30).toString())
        .attr("x2", targetNode.x.toString())
        .attr("y2", (targetNode.y - 30).toString());
    } else if (link.type === "horizontal" && sourceNode && targetNode) {
      gradient
        .attr("x1", (sourceNode.x + 30).toString())
        .attr("y1", sourceNode.y.toString())
        .attr("x2", (targetNode.x - 30).toString())
        .attr("y2", targetNode.y.toString());
    } else if (link.type.startsWith("corner")) {
      gradient
        .attr("gradientUnits", "objectBoundingBox")
        .attr("x1", "0%")
        .attr("y1", "0%")
        .attr("x2", "100%")
        .attr("y2", "100%");
    }

    // 添加渐变色彩停止点
    link.gradient.colors.forEach(colorStop => {
      gradient
        .append("stop")
        .attr("offset", colorStop.offset)
        .attr("stop-color", colorStop.color);
    });
  });

  // 绘制连接线
  const linkGroup = svg.append("g").attr("class", "links");

  linkData.value.forEach(link => {
    const sourceNode = nodeData.value.find(n => n.id === link.source)!;
    const targetNode = nodeData.value.find(n => n.id === link.target)!;

    let path: string ='';
    const radius = 10;

    if (link.type === "vertical") {
      const startX = sourceNode.x;
      const startY = sourceNode.y + 30;
      const endX = targetNode.x;
      const endY = targetNode.y - 30;
      path = `M ${startX} ${startY} L ${endX} ${endY}`;
    } else if (link.type === "horizontal") {
      const startX = sourceNode.x + 30;
      const startY = sourceNode.y;
      const endX = targetNode.x - 30;
      const endY = targetNode.y;
      path = `M ${startX} ${startY} L ${endX} ${endY}`;
    } else if (link.type === "corner-left") {
      const solarOffsetX = -5;
      const loadOffsetY = -5;
      const startX = sourceNode.x + solarOffsetX;
      const startY = sourceNode.y + 30;
      const endX = targetNode.x + 30;
      const endY = targetNode.y + loadOffsetY;

      path = `M ${startX} ${startY}
              L ${startX} ${endY - radius}
              Q ${startX} ${endY} ${startX - radius} ${endY}
              L ${endX} ${endY}`;
    } else if (link.type === "corner-right") {
      const solarOffsetX = 5;
      const gridOffsetY = -5;
      const startX = sourceNode.x + solarOffsetX;
      const startY = sourceNode.y + 30;
      const endX = targetNode.x - 30;
      const endY = targetNode.y + gridOffsetY;

      path = `M ${startX} ${startY}
              L ${startX} ${endY - radius}
              Q ${startX} ${endY} ${startX + radius} ${endY}
              L ${endX} ${endY}`;
    } else if (link.type === "corner-down") {
      let startX, startY, endX, endY;

      if (link.source === "load") {
        const loadOffsetY = 5;
        const batteryOffsetX = -5;
        startX = sourceNode.x + 30;
        startY = sourceNode.y + loadOffsetY;
        endX = targetNode.x + batteryOffsetX;
        endY = targetNode.y - 30;

        path = `M ${startX} ${startY}
                L ${endX - radius} ${startY}
                Q ${endX} ${startY} ${endX} ${startY + radius}
                L ${endX} ${endY}`;
      } else {
        const gridOffsetX = 5;
        startX = sourceNode.x + gridOffsetX;
        startY = sourceNode.y + gridOffsetX;
        endX = targetNode.x + 5;
        endY = targetNode.y - 30;

        path = `M ${startX} ${startY}
                L ${endX + radius} ${startY}
                Q ${endX} ${startY} ${endX} ${startY + radius}
                L ${endX} ${endY}`;
      }
    }

    // 绘制主连线路径
    const pathElement = linkGroup
      .append("path")
      .attr("id", `${link.id}-path`)
      .attr("d", path)
      .attr("stroke", link.hasFlow ? `url(#${link.gradient.id})` : "#d1d5db")
      .attr(
        "stroke-width",
        link.type === "vertical" || link.type === "horizontal" ? 3 : 2
      )
      .attr("fill", "none")
      .attr("opacity", link.hasFlow ? 1 : 0.4)
      .attr("stroke-linecap", "round")
      .attr("stroke-linejoin", "round")
      .style(
        "filter",
        link.hasFlow ? "drop-shadow(0px 2px 4px rgba(0,0,0,0.3))" : "none"
      );

    // 创建粒子动画
    createParticleAnimation(linkGroup, pathElement, link, 1);
  });

  // 绘制节点
  const nodeGroup = svg.append("g").attr("class", "nodes");

  nodeData.value.forEach(node => {
    const group = nodeGroup
      .append("g")
      .attr("transform", `translate(${node.x}, ${node.y})`)
      .style("cursor", "pointer");

    // 节点背景圆圈
    group
      .append("circle")
      .attr("r", 30)
      .attr("fill", "#ffffff")
      .attr("stroke", "#e0e0e0")
      .attr("stroke-width", 2)
      .style("filter", "drop-shadow(0px 2px 8px rgba(0,0,0,0.1))")
      .on("mouseover", function () {
        d3.select(this)
          .transition()
          .duration(200)
          .attr("r", 35)
          .attr("stroke", node.color);
      })
      .on("mouseout", function () {
        d3.select(this)
          .transition()
          .duration(200)
          .attr("r", 30)
          .attr("stroke", "#e0e0e0");
      });

    // 节点图标
    group
      .append("image")
      .attr("href", node.image)
      .attr("x", -15)
      .attr("y", -15)
      .attr("width", 30)
      .attr("height", 30);

    // 功率文字
    group
      .append("text")
      .attr("x", 0)
      .attr("y", 50)
      .attr("text-anchor", "middle")
      .attr("font-size", "12")
      .attr("font-weight", "bold")
      .attr("fill", "#2c3e50")
      .text(node.power);

    // 标签文字
    group
      .append("text")
      .attr("x", 0)
      .attr("y", 65)
      .attr("text-anchor", "middle")
      .attr("font-size", "10")
      .attr("fill", "#64748b")
      .text(node.label);
  });
};

// 更新图表数据
const updateGraph = () => {
  if (!svg) return;

  try {
    createEnergyFlow();
  } catch (error) {
    console.warn("Update error:", error);
  }
};

// 监听数据变化
watch(
  () => flowData.value,
  () => {
    updateGraph();
  },
  { deep: true }
);

// 响应式处理
const handleResize = () => {
  if (!svg || !containerRef.value) return;
  createEnergyFlow();
};

// ResizeObserver 监听容器尺寸变化
let resizeObserver: ResizeObserver | null = null;
let intersectionObserver: IntersectionObserver | null = null;

// 初始化图表的函数
const initChart = () => {
  updateContainerSize();
  const { width, height } = containerSize.value;

  // 只有当容器有有效尺寸时才绘制
  if (width > 0 && height > 0) {
    createEnergyFlow();
  }
};

onMounted(async () => {
  await nextTick();

  // 加载数据 - 已注释，使用模拟数据
  // await loadEnergyData();

  if (containerRef.value) {
    // 使用IntersectionObserver确保容器可见时再初始化
    intersectionObserver = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // 容器可见时初始化图表
          setTimeout(initChart, 50);
          // 初始化完成后停止观察
          intersectionObserver?.disconnect();
        }
      });
    });
    intersectionObserver.observe(containerRef.value);

    // 监听容器尺寸变化
    resizeObserver = new ResizeObserver(() => {
      handleResize();
    });
    resizeObserver.observe(containerRef.value);
  }

  // 监听窗口大小变化
  window.addEventListener("resize", handleResize);
});

onUnmounted(() => {
  clearAllAnimations();
  window.removeEventListener("resize", handleResize);

  // 清理ResizeObserver
  if (resizeObserver) {
    resizeObserver.disconnect();
    resizeObserver = null;
  }

  // 清理IntersectionObserver
  if (intersectionObserver) {
    intersectionObserver.disconnect();
    intersectionObserver = null;
  }
});
</script>

<style scoped>
.energy-flow-container {
  position: relative;
  overflow: hidden;
  border-radius: 8px;
  background: #ffffff;
}

.energy-flow-container :deep(svg) {
  width: 100%;
  height: 100%;
}
</style>
